/*
 * ThinktableMainJPanel.java
 *
 * Created on 23.01.2009, 20:47:46
 */
package morenoapp.components.thinktable;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTable.PrintMode;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import morenoapp.MorenoApp;
import morenoapp.components.common.table.renderer.StyledTableValue;
import morenoapp.model.enums.MorenoQuestionType;
import morenoapp.util.EnumWrapper;
import morenoapp.util.DescriptionSupportComboBoxRenderer;
import morenoapp.util.I18N;
import morenoapp.util.MorenoUtil;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.jdesktop.application.Action;

/**
 * 
 * @author dmitry.mamonov
 */
public class ThinktableMainJPanel extends javax.swing.JPanel {
    protected EnumWrapper<MorenoQuestionType> filterQuestionType = new EnumWrapper<MorenoQuestionType>(MorenoQuestionType.class, null);
    protected ThinktableTableJPanel thinktableTableJPanel;
    protected JCheckBox checkBoxShowTotalsByEachQuestion;

    /** Creates new form ThinktableMainJPanel */
    public ThinktableMainJPanel() {
        initComponents();

        thinktableTableJPanel = new ThinktableTableJPanel();
        final ThinktableQuestionsFilterJPanel questionsFilterJPanel = new ThinktableQuestionsFilterJPanel();
        thinktableTableJPanel.getThinktableTableModel().setQuestionsFilter(questionsFilterJPanel);
        questionsFilterJPanel.setFilteredTableModel(thinktableTableJPanel.getThinktableTableModel());

        jComboBoxFilterByQuestionType.setModel(
                new DefaultComboBoxModel(
                EnumWrapper.createWrappersNullAndAll(
                MorenoQuestionType.class)));
        jComboBoxFilterByQuestionType.setRenderer(new DescriptionSupportComboBoxRenderer());
        jComboBoxFilterByQuestionType.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                questionsFilterJPanel.applyFilterByQuestionType(((EnumWrapper<MorenoQuestionType>) e.getItem()).getWrappedValue());
            }
        });

        jToolBar.add(questionsFilterJPanel);
        jPanelPlacement.add(thinktableTableJPanel, BorderLayout.CENTER);
        
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jFileChooser = new javax.swing.JFileChooser();
        jToolBar = new javax.swing.JToolBar();
        jButtonPrint = new javax.swing.JButton();
        jButtonExport = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        jLabelFilter = new javax.swing.JLabel();
        jComboBoxFilterByQuestionType = new javax.swing.JComboBox();
        jPanelPlacement = new javax.swing.JPanel();

        jFileChooser.setName("jFileChooser"); // NOI18N

        setName("Form"); // NOI18N

        jToolBar.setFloatable(false);
        jToolBar.setRollover(true);
        jToolBar.setName("jToolBar"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(morenoapp.MorenoApp.class).getContext().getActionMap(ThinktableMainJPanel.class, this);
        jButtonPrint.setAction(actionMap.get("actionPrintThinktable")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(morenoapp.MorenoApp.class).getContext().getResourceMap(ThinktableMainJPanel.class);
        jButtonPrint.setIcon(resourceMap.getIcon("jButtonPrint.icon")); // NOI18N
        jButtonPrint.setText(resourceMap.getString("jButtonPrint.text")); // NOI18N
        jButtonPrint.setToolTipText(resourceMap.getString("jButtonPrint.toolTipText")); // NOI18N
        jButtonPrint.setFocusable(false);
        jButtonPrint.setName("jButtonPrint"); // NOI18N
        jButtonPrint.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar.add(jButtonPrint);

        jButtonExport.setAction(actionMap.get("actionExportForTableProcessor")); // NOI18N
        jButtonExport.setIcon(resourceMap.getIcon("jButtonExport.icon")); // NOI18N
        jButtonExport.setText(resourceMap.getString("jButtonExport.text")); // NOI18N
        jButtonExport.setToolTipText(resourceMap.getString("jButtonExport.toolTipText")); // NOI18N
        jButtonExport.setFocusable(false);
        jButtonExport.setName("jButtonExport"); // NOI18N
        jButtonExport.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar.add(jButtonExport);

        jSeparator1.setName("jSeparator1"); // NOI18N
        jToolBar.add(jSeparator1);

        jLabelFilter.setText(resourceMap.getString("jLabelFilter.text")); // NOI18N
        jLabelFilter.setToolTipText(resourceMap.getString("jLabelFilter.toolTipText")); // NOI18N
        jLabelFilter.setName("jLabelFilter"); // NOI18N
        jToolBar.add(jLabelFilter);

        jComboBoxFilterByQuestionType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        jComboBoxFilterByQuestionType.setMaximumSize(new java.awt.Dimension(80, 32767));
        jComboBoxFilterByQuestionType.setName("jComboBoxFilterByQuestionType"); // NOI18N
        jToolBar.add(jComboBoxFilterByQuestionType);

        jPanelPlacement.setName("jPanelPlacement"); // NOI18N
        jPanelPlacement.setLayout(new java.awt.BorderLayout());

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, 547, Short.MAX_VALUE)
                .addContainerGap())
            .addComponent(jPanelPlacement, javax.swing.GroupLayout.DEFAULT_SIZE, 557, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanelPlacement, javax.swing.GroupLayout.DEFAULT_SIZE, 285, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    @Action
    public void actionPrintThinktable() {
        try {
            thinktableTableJPanel.getJTable().print(PrintMode.FIT_WIDTH);
        } catch (PrinterException ex) {
            ex.printStackTrace(); //TODO add handler
        }
    }

    @Action
    public void actionExportForTableProcessor() {
//        ExportTableJDialog exportDialog = new ExportTableJDialog(Application.getInstance(MorenoApp.class).getMainFrame(), true);
//        exportDialog.setTableModelToExport(thinktableTableJPanel.getThinktableTableModel());
//        exportDialog.setVisible(true);
        jFileChooser.setApproveButtonText(I18N.get("select_file_to_exporst_poll")); //I18N
        jFileChooser.setMultiSelectionEnabled(false);
        jFileChooser.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                return f.getName().toLowerCase().endsWith(".xls")==true;
            }

            @Override
            public String getDescription() {
                return I18N.get("excel_file_type_filter");
            }
        });
        File lastFile = MorenoApp.getApplicationData().getLastExportedTableFile();
        if (lastFile.isFile()) {
            jFileChooser.setSelectedFile(lastFile);
        } else {
            jFileChooser.setCurrentDirectory(lastFile);
        }

        if (JFileChooser.APPROVE_OPTION == jFileChooser.showOpenDialog(SwingUtilities.getWindowAncestor(this))) {
            MorenoApp.getApplicationData().setLastExportedTableFile(jFileChooser.getSelectedFile());
            
            final File targetFile;
            if (jFileChooser.getSelectedFile().getName().toLowerCase().endsWith(".xls")==false){
                targetFile = new File(jFileChooser.getSelectedFile().getAbsolutePath()+".xls");
                int answer = JOptionPane.showConfirmDialog(
                        SwingUtilities.getRoot(ThinktableMainJPanel.this),
                        I18N.get("thinktable.target_file_will_be")+" '"+targetFile.getName()+"'");
                if (answer!=JOptionPane.OK_OPTION){
                    return;
                }
            } else {
                targetFile =  jFileChooser.getSelectedFile();
            }

            new Runnable() {
                Workbook wb = new HSSFWorkbook();
                Sheet s = wb.createSheet();
                CellStyle styleCentered = wb.createCellStyle();
                CellStyle styleLeft = wb.createCellStyle();
                CellStyle styleRight = wb.createCellStyle();
                Map<Color, Font> fontsMap = new HashMap();

                {
                    styleCentered.setAlignment(CellStyle.ALIGN_CENTER);
                    styleLeft.setAlignment(CellStyle.ALIGN_LEFT);
                    styleRight.setAlignment(CellStyle.ALIGN_RIGHT);
                }

                Font getFont(Color c) {
                    if (fontsMap.containsKey(c) == false) {
                        Font font = wb.createFont();
                        font.setColor(MorenoUtil.getClosestHSSFColor(c).getIndex());
                        fontsMap.put(c, font);
                    }
                    Font font = fontsMap.get(c);
                    return font;
                }

                HSSFRichTextString htmlToRichTextString(String html, Color defaultColor) {
                    try {
                        StringBuilder text = new StringBuilder();
                        TreeMap<Integer, Color> colorsMap = new TreeMap<Integer, Color>();
                        colorsMap.put(0, defaultColor);
                        boolean inTag = false;

                        Color lastColor = null;
                        for (int i = 0; i < html.length(); i++) {
                            char ch = html.charAt(i);
                            if (ch == '<') {
                                if (html.substring(i).startsWith("</font>") && lastColor != null) {
                                    lastColor = null;
                                    colorsMap.put(text.length(), Color.black);
                                }
                                inTag = true;
                            } else if (ch == '>') {
                                inTag = false;
                                continue;
                            }
                            if (inTag == true && ch == '#') {
                                String strColor = html.substring(i + 1, i + 7);
                                Color color = MorenoUtil.stringToColor(strColor);
                                colorsMap.put(text.length(), color);
                                lastColor = color;
                            } else if (inTag == false) {
                                text.append(ch);
                            }
                        }
                        colorsMap.put(text.length(), Color.black); //dummy

                        HSSFRichTextString richValue = new HSSFRichTextString(text.toString());
                        for (Map.Entry<Integer, Color> e : colorsMap.entrySet()) {
                            Map.Entry<Integer, Color> next = colorsMap.ceilingEntry(e.getKey() + 1);
                            if (next != null) {
                                richValue.applyFont(e.getKey(), next.getKey(), getFont(e.getValue()));
                            }
                        }
                        return richValue;
                    } catch (Exception e) {
                        return new HSSFRichTextString("" + e.getMessage());
                    }
                }

                CellStyle getStyle(StyledTableValue.Aligment aligment) {
                    switch (aligment) {
                        case Center:
                            return styleCentered;
                        case Left:
                            return styleLeft;
                        case Right:
                            return styleRight;
                        default:
                            return styleLeft;
                    }
                }

                @Override
                public void run() {
                    ThinktableTableModel model = thinktableTableJPanel.getThinktableTableModel();
                    int rowCount = model.getRowCount();
                    int colCount = model.getColumnCount();

                    Row header = s.createRow(0);
                    for (int colNum = 0; colNum < colCount; colNum++) {
                        Cell c = header.createCell(colNum);

                        String value = model.getColumnMeta(colNum).getName();
                        HSSFRichTextString richValue = htmlToRichTextString(value, Color.BLACK);
                        Font coloredFont = getFont(Color.black);
                        Font font = wb.createFont();
                        font.setColor(coloredFont.getColor());
                        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                        richValue.applyFont(font);
                        c.setCellValue(richValue);
                        if (value.contains("center")) {
                            c.setCellStyle(styleCentered);
                        }
                    }

                    for (int rowNum = 0; rowNum < rowCount; rowNum++) {
                        Row r = s.createRow(rowNum + 1);
                        for (int colNum = 0; colNum < colCount; colNum++) {
                            Cell c = r.createCell(colNum);
                            StyledTableValue styledValue = (StyledTableValue) model.getValueAt(rowNum, colNum);
                            String htmlValue = styledValue.getValue();
                            c.setCellValue(htmlToRichTextString(htmlValue, styledValue.getForeground()));
                            c.setCellStyle(getStyle(styledValue.getAligh()));
                        }
                    }
                    FileOutputStream fout = null;
                    try {
                        fout = new FileOutputStream(targetFile);
                        wb.write(fout);
                        fout.close();

                        if (JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(
                                SwingUtilities.getRoot(ThinktableMainJPanel.this),
                                I18N.get("table_successfully_exported_open_file_Q"), I18N.get("open_file_Q"), JOptionPane.YES_NO_OPTION)) {
                            Desktop.getDesktop().open(targetFile);
                        }
                    } catch (IOException ex) {
                        JOptionPane.showMessageDialog(
                                SwingUtilities.getRoot(ThinktableMainJPanel.this),
                                ex.getMessage());
                    } finally {
                        if (fout != null) {
                            try {
                                fout.close();
                            } catch (IOException ex) {
                                Logger.getLogger(ThinktableMainJPanel.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                    }
                }
            }.run();
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonExport;
    private javax.swing.JButton jButtonPrint;
    private javax.swing.JComboBox jComboBoxFilterByQuestionType;
    private javax.swing.JFileChooser jFileChooser;
    private javax.swing.JLabel jLabelFilter;
    private javax.swing.JPanel jPanelPlacement;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar jToolBar;
    // End of variables declaration//GEN-END:variables
}
